package de.fhin.mas.util;

/**
 * Klasse die einige Funktionen für Koordinaten implementiert
 * 
 * @author Matthias Wilhelm
 * 
 */
public class Coordinate {
	private int x = 0;
	private int y = 0;

	public Coordinate(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public void set_Coordinate(int x, int y) {
		this.x = x;
		this.y = y;
	}

	public void set_Coordinate(Coordinate coordinate) {
		x = coordinate.x;
		y = coordinate.y;
	}

	public void setX(int x) {
		this.x = x;
	}

	public void setY(int y) {
		this.y = y;
	}

	public Coordinate get_Coordinate() {
		return this;
	}

	public int getX() {
		return this.x;
	}

	public int getY() {
		return this.y;
	}

	public double distance(Coordinate coordinate) {
		double x = this.x - coordinate.x;
		double y = this.y - coordinate.y;

		if (x == 0) {
			return Math.abs(y);
		} else if (y == 0) {
			return Math.abs(x);
		} else {
			return Math.sqrt(x * x + y * y);
		}
	}

	/** Rechnet die Koordinate in der Mitte zwischen 2 Koordinaten aus **/
	public Coordinate middle(Coordinate coordinate) {
		x = this.x + (coordinate.x - this.x) / 2;
		y = this.y + (coordinate.y - this.y) / 2;
		return new Coordinate(x, y);
	}

	/** Gibt die Steigung zwischen 2 Koordinaten als Koordinate zurück */
	public double gradient(Coordinate coordinate) {
		double x = this.x - coordinate.x;
		double y = this.y - coordinate.y;
		if (x != 0) {
			return y / x;
		} else {
			return 0;
		}
	}

	public double vertical_gradient(Coordinate coordinate) {
		return -1 / this.gradient(coordinate);
	}

	/** Gibt den Winkel zwischen 2 Koordinaten zurück */
	public double angle(Coordinate coordinate) {
		double adjacent = coordinate.x - this.x;
		double opposite = coordinate.y - this.y;

		if (opposite == 0) {
			if (adjacent < 0) {
				return 180;
			} else {
				return 0;
			}

		} else {
			double angle = Math.atan((adjacent / opposite));
			if (opposite < 0) {
				angle = (2 * Math.PI) - angle;
			}
			return ((angle * 360) / (2 * Math.PI)) % 360;
		}

	}

	public void add(Coordinate coordinate) {
		this.x = this.x + coordinate.x;
		this.y = this.y + coordinate.y;
	}

	/**
	 * 
	 * 
	 * @param coordinate
	 * @return
	 */
	public RelativeCoordinate get_relativeCoordinate(Coordinate coordinate) {
		int angle = (int) Math.round(this.angle(coordinate));
		int distance = (int) Math.round(this.distance(coordinate));
		return new RelativeCoordinate(angle, distance);
	}

	public void println() {
		System.out.println(this.toString());
	}

	@Override
	public String toString() {
		return "( " + x + " | " + y + " )";
	}
}
